using System.Linq;
using System.Reflection;
using CAPDemo.BasketService.Models;
using CAPDemo.Events;
using DotNetCore.CAP;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace CAPDemo.BasketService
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<BasketDbContext>(options => options.UseMySql(Configuration.GetConnectionString("Default"), MySqlServerVersion.LatestSupportedServerVersion));
            services.AddCap(x =>
            {
                x.UseEntityFramework<BasketDbContext>();
                x.UseDashboard();
                x.UseRabbitMQ(rb =>
                {
                    rb.HostName = Configuration.GetValue<string>("RabbitMQ:HostName");
                    rb.Port = Configuration.GetValue<int>("RabbitMQ:Port");
                    rb.VirtualHost = Configuration.GetValue<string>("RabbitMQ:VirtualHost");
                    rb.UserName = Configuration.GetValue<string>("RabbitMQ:UserName");
                    rb.Password = Configuration.GetValue<string>("RabbitMQ:Password");
                    rb.ExchangeName = Configuration.GetValue<string>("RabbitMQ:ExchangeName");
                });

                x.SucceedMessageExpiredAfter = 24 * 3600;
                x.FailedRetryCount = 5;
            });
            services.AddControllers();

            Assembly.GetExecutingAssembly()
                .GetTypes()
                .Where(item => item.GetInterfaces().Where(i => i.IsGenericType).Any(i => i.GetGenericTypeDefinition() == typeof(IEventHandler<>)) && !item.IsAbstract && !item.IsInterface)
                .ToList()
                .ForEach(assignedTypes =>
                {
                    var serviceType = assignedTypes.GetInterfaces().First(i => i.GetGenericTypeDefinition() == typeof(IEventHandler<>));
                    services.AddTransient(serviceType, assignedTypes);
                });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseAuthorization();
            app.UseCapDashboard();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
